/***************************************************************************
| File: monitor.c
|
| Autor: Joao Carlos Bittencourt, Vinicius Bittencourt, Italo Santos,
		 from work by Carlos Almeida (IST), from work by Jose Rufino 
		 (IST/INESC), from an original by Leendert Van Doorn
| Data:  Maio 2012
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "../include/commands.h"
#include "../include/monitor.h"

/*-------------------------------------------------------------------------+
| Variable and constants definition
+--------------------------------------------------------------------------*/ 
const char TitleMsg[] = "\n Application Control Monitor\n";
const char InvalMsg[] = "\nInvalid command!";

struct 	command_d {
  void  (*cmd_fnct)(int, char**);
  char*	cmd_name;
  char*	cmd_help;
} const commands[] = {
  {cmd_help, "help","                 help"},
  {cmd_exit, "exit","                 exit"},
  {cmd_ini,  "ini","<d>               initialize device (0/1) ser0/ser1"},
  {cmd_rc,   "rc","                   read clock"},
  {cmd_sc,   "sc","<h> <m> <s>        send message"},
  {cmd_rtl,  "rtl","                  read temperature and luminosity"},
  {cmd_mpm,  "mpm","<p>               modify monitoring period (seconds - 0 deactivate)"},
  {cmd_mti,  "mti","<t>               modify inactivity time (minutes - 0 deactivate)"},  
  {cmd_ra,   "ra","                   read alarms"},
  {cmd_da,   "da","<h> <m> <s>        define alarm clock"},
  {cmd_dt,   "dt","<t>                define alarm temperature"},
  {cmd_dl,   "dl","<l>                define alarm luminosity"},
  {cmd_aa,   "aa","                   activate/deactivate alarms"},
  {cmd_ir,   "ir","                   information about registers"},
  {cmd_trc,  "trc","<n>               transfer n registers from current iread position"},
  {cmd_tri,  "tri","<n> <i>           transfer n registers from index i"},
  {cmd_test, "test","<arg1> <arg2>    test command"}
};

#define NCOMMANDS  (sizeof(commands)/sizeof(struct command_d))
#define ARGVECSIZE 10
#define MAX_LINE   50

/*-------------------------------------------------------------------------+
| Function: cmd_help - provides a rudimentary help
+--------------------------------------------------------------------------*/ 
void cmd_help (int argc, char **argv)
{
  int i;

  printf("%s\n", TitleMsg);
  for (i=0; i<NCOMMANDS; i++)
    printf("%s %s\n", commands[i].cmd_name, commands[i].cmd_help);
}

/*-------------------------------------------------------------------------+
| Function: getline        (called from monitor) 
+--------------------------------------------------------------------------*/ 
int my_getline (char** argv, int argvsize)
{
  static char line[MAX_LINE];
  char *p;
  int argc;

  fgets(line, MAX_LINE, stdin);

  /* Break command line into an o.s. like argument vector,
     i.e. compliant with the (int argc, char **argv) specification --------*/

  for (argc=0,p=line; (*line != '\0') && (argc < argvsize); p=NULL,argc++) {
    p = strtok(p, " \t\n");
    argv[argc] = p;
    if (p == NULL) return argc;
  }
  argv[argc] = p;
  return argc;
}

/*-------------------------------------------------------------------------+
| Function: monitor        (called from main) 
+--------------------------------------------------------------------------*/ 
void monitor (void)
{
  static char *argv[ARGVECSIZE+1], *p;
  int argc, i;

  printf("%s Type 'help' for help\n", TitleMsg);
  for (;;) {
    printf("\nCmd> ");
    /* Reading and parsing command line  ----------------------------------*/
    if ((argc = my_getline(argv, ARGVECSIZE)) > 0) {
      for (p=argv[0]; *p != '\0'; *p=tolower(*p), p++);
      for (i = 0; i < NCOMMANDS; i++) 
	    if (strcmp(argv[0], commands[i].cmd_name) == 0) 
	       break;
      /* Executing commands -----------------------------------------------*/
      if (i < NCOMMANDS)
	       commands[i].cmd_fnct (argc, argv);
      else  
	       printf("%s", InvalMsg);
    } /* if my_getline */
  } /* forever */
}